package com.nulgame.bukkit.plugin.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.bukkit.ChatColor;
import org.bukkit.configuration.file.YamlConfiguration;

import com.nulgame.bukkit.plugin.logger.ASLogger;
import com.nulgame.bukkit.plugin.model.AntiSpamConfiguration;
import com.nulgame.bukkit.plugin.resource.Resource;

public class Util {
	public static AntiSpamConfiguration loadConfig(File configFile){
		AntiSpamConfiguration configuration = new AntiSpamConfiguration();
		YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
		
		configuration.options.antiChatOverFlow = config.getBoolean("Options.AntiChatOverFlow", false);
		configuration.options.antiChatSpam =  config.getBoolean("Options.AntiChatSpam", false);
		configuration.options.antiWord =  config.getBoolean("Options.AntiWord", false);
		configuration.options.antiWordCap =  config.getBoolean("Options.AntiWordCap", false);
		configuration.options.antiIPAddress =  config.getBoolean("Options.AntiIPAddress", false);
		configuration.options.antiServerAddress =  config.getBoolean("Options.AntiServerAddress", false);
		configuration.options.replacement =  config.getBoolean("Options.AntiChatWithReplacement", false);
		
		ChatColor color = null;
		String stringChatColor = config.getString("GlobalSetting.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
		
		if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
			ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in Global Setting is not valid color. The white color will be used");
			color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
		}else{
			color =  ChatColor.getByChar(stringChatColor.charAt(0));
		}
		configuration.globalSetting.responseTextColor = color;
		
		//Load AntiChatOverFlow
		configuration.antiChatOverFlow.inMillisTime = config.getLong("AntiChatOverFlow.InMillisTime", Resource.ANTI_CHAT_OVERFLOW_IN_MILLIS_TIME_DEFAULT);
		configuration.antiChatOverFlow.responseToPlayer = config.getString("AntiChatOverFlow.ResponseToPlayer", Resource.ANTI_CHAT_OVERFLOW_RESPONSE_TO_PLAYER_DEFAULT);
		if(config.contains("AntiChatOverFlow.ResponseTextColor")){
			stringChatColor = config.getString("AntiChatOverFlow.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor in AntiChatOverFlow is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiChatOverFlow.responseTextColor = color;
		
		//Load AntiChatSpam
		configuration.antiChatSpam.allowedInfraction = config.getInt("AntiChatSpam.AllowedInfraction", Resource.ANTI_CHAT_SPAM_ALLOWED_INFRACTION_DEFAULT);
		configuration.antiChatSpam.inMillisTime = config.getLong("AntiChatSpam.InMillisTime", Resource.ANTI_CHAT_SPAM_IN_MILLIS_TIME_DEFAULT);
		configuration.antiChatSpam.responseToPlayer = config.getString("AntiChatSpam.ResponseToPlayer", Resource.ANTI_CHAT_SPAM_RESPONE_TO_PLAYER_DEFAULT);
		if(config.contains("AntiChatSpam.ResponseTextColor")){
			stringChatColor = config.getString("AntiChatSpam.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in AntiChatSpam is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiChatSpam.responseTextColor = color;
		
		//Load AnitWord
		configuration.antiWord.words = (List<String>) config.getList("AntiWord.Words", new ArrayList<String>());
		configuration.antiWord.responseToPlayer = config.getString("AntiWord.ResponseToPlayer", Resource.ANTI_WORD_RESPONSE_TO_PLAYER_DEFAULT);
		if(config.contains("AntiWord.ResponseTextColor")){
			stringChatColor = config.getString("AntiWord.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in AntiWord is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiWord.responseTextColor = color;
		
		//Load AntiWordCap
		configuration.antiWordCap.allowedPercentage = config.getDouble("AntiWordCap.AllowedPercentage", Resource.ANTI_WORD_ALLOWED_PERCENTAGE_DEFAULT);
		configuration.antiWordCap.responseToPlayer = config.getString("AntiWordCap.ResponseToPlayer", Resource.ANTI_WORD_CAP_RESPONSE_TO_PLAYER_DEFAULT);
		if(config.contains("AntiWordCap.ResponseTextColor")){
			stringChatColor = config.getString("AntiWordCap.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in AntiWordCap is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiWordCap.responseTextColor = color;
		
		//Load AntiIPAddress
		configuration.antiIPAddress.responseToPlayer = config.getString("AntiIPAddress.ResponseToPlayer", Resource.ANTI_WORD_CAP_RESPONSE_TO_PLAYER_DEFAULT);
		if(config.contains("AntiIPAddress.ResponseTextColor")){
			stringChatColor = config.getString("AntiIPAddress.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in AntiIPAddress is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiIPAddress.responseTextColor = color;
		
		//Load AntiServerAddress
		configuration.antiServerAddress.domainTypes = (List<String>) config.getList("AntiServerAddress.DomainType", new ArrayList<String>());
		configuration.antiServerAddress.responseToPlayer = config.getString("AntiServerAddress.ResponseToPlayer", Resource.ANTI_SERVER_ADDRESS_DEFAULT);
		if(config.contains("AntiServerAddress.ResponseTextColor")){
			stringChatColor = config.getString("AntiServerAddress.ResponseTextColor", Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			if(stringChatColor.length() < 1 || stringChatColor.length() != 1 || ChatColor.getByChar(stringChatColor.charAt(0)) == null){
				ASLogger.info("Error, the ResponseTextColor " + stringChatColor + " in AntiServerAddress is not valid color. The white color will be used");
				color =  ChatColor.getByChar(Resource.GLOBAL_SETTING_RESPONSE_TEXT_COLOR);
			}else{
				color =  ChatColor.getByChar(stringChatColor.charAt(0));
			}
		}else{
			color = configuration.globalSetting.responseTextColor;
		}
		configuration.antiServerAddress.responseTextColor = color;
		
		//Load AntiChatWithReplacement
		
		List<String> rules = (List<String>) config.getList("AntiChatWithReplacement.Rules", new ArrayList<String>());
		for(String rule : rules){
			String[] operands = rule.split(Resource.RULE_DELIMITER_PATERN);
			if(operands != null && operands.length == 2){
				configuration.replacement.left.add(operands[0]);
				configuration.replacement.right.add(operands[1]);
			}else{
				ASLogger.info("There is invalid rule from AntiChatWithReplacement.Rules, ignoring it");
			}
		}
		
		return configuration;
	}
	
	public static <K, T, X extends T> T getWithCreation(K key, Map<K, T> map, Class<X> c) {
        T result = map.get(key);
        if (result == null) {
            result = map.get(key);
            if (result == null) {
                try {
                    result = c.newInstance();
                } catch (Exception e) {
                    throw new RuntimeException("Error in getWithCreation()", e);
                }
                map.put(key, result);
            }
        }
        return result;
    }
	
	public static int countCapitalChar(String str){
		int count = 0;
		if(str == null || str.isEmpty()){
			return count;
		}
		for(Character ch : str.toCharArray()){
			if(ch >= 65 && ch <= 90){
				count++;
			}
		}
		return count;
	}
	
	public static boolean validIP(String ip) {
	    try {
	        if (ip == null || ip.isEmpty()) {
	            return false;
	        }

	        String[] parts = ip.split( "\\." );
	        if ( parts.length != 4 ) {
	            return false;
	        }

	        for ( String s : parts ) {
	            int i = Integer.parseInt( s );
	            if ( (i < 0) || (i > 255) ) {
	                return false;
	            }
	        }
	        if(ip.endsWith(".")) {
	                return false;
	        }

	        return true;
	    } catch (NumberFormatException nfe) {
	        return false;
	    }
	}
}
